#ifndef MAIN_COLOR_H_INCLUDED
#define MAIN_COLOR_H_INCLUDED
extern "C" {

#include "../inc/defs.h"
#include "../inc/routines.h"

bool doTabu(int colors,GraphC *g, int fixLong, float propLong, int maxIt, int verbosity, char *instFile, const char* solfilename, int nRestart);

void printTabuProcessInfo(GraphC *g, int type, int result, char *instFile, const char* solfilename, int colors, int execTime, int maxIt, int fixLong, float propLong, int stopIt, int nRestart);

inline bool color(char* instFile, int colors, GraphC* graph)
{
	GraphC *g;
	int verbosity = DEFAULTVERB;
	//Tabu search param
	int fixLong,maxIt,nRestart;
	float propLong;
	//Simulated Annealing param
	int maxItImprove,maxItConstTemp;
	float startTemp,minTemp,tempFactor;	
	
	srand((unsigned int)time(NULL));
	//g=loadGraph(instFile);
    g = graph;
	//Set default tabu search values
	maxIt=1000;
	fixLong=g->numNodes/2;
	propLong=0.5;
	nRestart=0;
	
	//Set default Simulated Annealing values
	startTemp=getNodeMaxOrder(g);
	minTemp=0.01;
	tempFactor=0.999;
	maxItImprove=0;
	maxItConstTemp=100;
	
	//Reading configuration file
	readConfFile(&nRestart,&maxIt,&fixLong,&propLong,&maxItImprove,&startTemp,&minTemp,&tempFactor,&maxItConstTemp);

// 	doSA(colors,g,verbosity,instFile,startTemp,minTemp,tempFactor,maxItImprove,maxItConstTemp);
    char outFile[100];
    sprintf(outFile, "%s_res", instFile);
	return doTabu(colors,g,fixLong,propLong,maxIt,verbosity,instFile, outFile,nRestart);
// 	doVNS(colors,g,verbosity,instFile,fixLong,propLong,maxIt);
}

inline bool doTabu(int colors,GraphC *g, int fixLong, float propLong, int maxIt, int verbosity, char *instFile, const char* solfilename, int nRestart)
{
	int startTime,stopTime,execTime;
	int result,stopIt,restIt,nR;
	int **adjColors;
	
	adjColors=NULL;
	nR=0;
	
  	//Number of colors chosen
  	//Build the random initial solution
  	randomColor(g,colors);

  	startTime=time(NULL);
  	result=findTabu(g,colors,fixLong,propLong,maxIt,&stopIt,&adjColors,FALSE);
  	restIt=stopIt;

  	bool found = false;

  	if(result==0)
  		found = true;
  	else
  	{
  		while(result!=0 && nR<nRestart)
  		{
  			nR++;
  			randomConflictingColor(g,colors,adjColors);
  			result=findTabu(g,colors,fixLong,propLong,maxIt,&stopIt,&adjColors,FALSE);
  			restIt+=stopIt;
  			
  			if(result==0)
  			{
  				found = true;
  				break;
  			}
  		}
  	}

  	if (found) {	
	  	stopTime=time(NULL);
  		execTime=stopTime-startTime;
	  	//printTabuProcessInfo(g,verbosity,result,instFile, solfilename,colors,execTime,maxIt,fixLong,propLong,restIt,nR);
	}
  	return found;
}

inline void printTabuProcessInfo(GraphC *g, int type, int result, char *instFile, const char *solfilename, int colors, int execTime, int maxIt, int fixLong, float propLong, int stopIt, int nRestart)
{
  
	FILE *fResults,*fLegalColoring;
	Node *n;
	
	fResults=fopen("results_tabu.txt","a");
	if(fResults==NULL)
	{
		printf("Error in opening results file\n");
		exit(EXIT_OPENFILE);
	}
	
	fprintf(fResults,"\n%s\t%d\t%d\t%d\t",instFile,g->numNodes,g->numEdges,colors);
	if(result==0)
		fprintf(fResults,"COLORED(C:%d)\t",result);
	else
		fprintf(fResults,"FAILED(C:%d)\t",result);

	fprintf(fResults,"%d\t%d\t%d\t%d\t%.2f\t%d",execTime,stopIt,maxIt,fixLong,propLong,nRestart);
	fclose(fResults);
  
	switch(type)
	{
		case 1: printf("Printing GraphC image\n");
			printDotOut(g->nodesList);
			system("dot out.dot -Tpng > out.png");
			break;
		case 2: printf("Printing adjacency list\n");
			printNodesList(g->nodesList);
			break;
		default:break;
	}
	
	if(result==0)
	{
		fLegalColoring=fopen(solfilename,"w");
		
		if(fLegalColoring==NULL)
		{
			printf("Error in opening coloring solution file\n");
			exit(EXIT_OPENFILE);
		}
			
		fprintf(fLegalColoring,"NODES\tCOLOR\n");
		
		n=firstNodesList(g->nodesList);
		while(!endNodesList(n,g->nodesList))
		{
			fprintf(fLegalColoring,"%d\t%d\n",n->id,n->color);
			n=nextNodesList(n);
		}
		
		fclose(fLegalColoring);
	}	
	else
	{
		printf("Not Printing %d-coloring solution for the current GraphC\n",colors);	
	}
}
}

#endif//MAIN_COLOR_H_INCLUDED
